﻿namespace SenenFernandez.DisplayManager.ViewModel
{
    using SenenFernandez.SmartExtensionMethods;

    using Microsoft.Win32;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Linq.Expressions;

    public class MainViewModel : INotifyPropertyChanged
    {
        private string title;
        private Display selectedMonitor;
        private IEnumerable<Display> monitors;
        private string alertText;

        public string Title
        {
            get { return title; }
            private set { SetTitle(value); }
        }

        public Display SelectedMonitor
        {
            get { return selectedMonitor; }
            set { SetSelectedMonitor(value); }
        }

        public IEnumerable<Display> Monitors
        {
            get { return monitors; }
        }

        public string AlertText
        {
            get { return alertText; }
            private set { SetAlertText(value); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public MainViewModel()
        {
            Title = Properties.Resources.ApplicationTitle;
            SetMonitors();
            SystemEvents.DisplaySettingsChanged += OnDisplaySettingsChanged;
        }

        private void SetTitle(string value)
        {
            if (!value.Equals(title))
            {
                title = value;
                RaisePropertyChanged(() => Title);
            }
        }

        private void SetSelectedMonitor(Display value)
        {
            if (value != selectedMonitor)
            {
                selectedMonitor = value;
                RaisePropertyChanged(() => SelectedMonitor);
            }
        }

        private void SetMonitors()
        {
            monitors = SmartScreenManager.Monitors;
            RaisePropertyChanged(() => Monitors);
            SelectedMonitor = Monitors.FirstOrDefault();
        }

        private void SetAlertText(string value)
        {
            if (!value.Equals(alertText))
            {
                alertText = value;
                RaisePropertyChanged(() => AlertText);
            }
        }

        private void OnDisplaySettingsChanged(object sender, EventArgs e)
        {
            AlertText = string.Format(Properties.Resources.DisplaySettingsChanged, DateTimeOffset.Now.ToString("yyyy/MM/dd HH:mm:ss zzz"));
            SetMonitors();
        }

        private void RaisePropertyChanged<T>(Expression<Func<T>> expression)
        {
            if (expression != null)
            {
                var memberExpression = expression.Body as MemberExpression;
                if (memberExpression != null)
                {
                    var propertyName = memberExpression.Member.Name;
                    if (propertyName != null)
                    {
                        var handler = PropertyChanged;
                        if (handler != null)
                        {
                            handler(this, new PropertyChangedEventArgs(propertyName));
                        }
                    }
                }
            }
        }
    }
}